﻿using System;
using System.Collections.Generic;
using System.Reflection;


/// <summary>
/// 表中可查询字段
/// </summary>
[System.Flags]
public enum Fields
{
    ProductName = 1,
    MedicineModelName = 2,
    Outlookc = 4,
    CompanyName_SC = 8,
    Unit = 16,
    SortName = 32,
    CompanyName_TB = 64,
    SortID = 128,
    GoodsName = 256,
    Factor = 512,
    Pack = 1024,
    PinyinCode = 2048,
    WBCode = 4096,
    QualityLevel = 8192,
    HospitalID = 16384,
    AreaID = 32768,
    HospitalName = 65536,
    OrderName = 131072,
    PlanTime = 262144,
    PlanEndTime = 524288,
    CompanyID_PS = 1048576,
    CompanyName_PS = 2097152,
    PurchaseCount = 4194304,
    Price = 8388608,
    DistributeCount = 16777216,
    WarehouseCount = 33554432,
    PurchaseAmount = 67108864,
    WarehouseAmount = 134217728

}
[System.Flags]
public enum GroupFields
{
    /// <summary>
    /// 采购总量
    /// SUM(PurchaseCount)
    /// </summary>
    [Enum("SUM(PurchaseCount)")]
    PurchaseCountTotal = 0x1,
    /// <summary>
    /// 平均采购价
    /// Avg(Price)
    /// </summary>
    [Enum("Avg(Price)")]
    PriceAvg = 0x2,
    /// <summary>
    /// 采购总金额
    /// SUM(PurchaseAmount)
    /// </summary>
    [Enum("SUM(PurchaseAmount)")]
    PurchaseAmountTotal = 0x4,
    /// <summary>
    /// 配送率
    /// SUM(DistributeCount) / SUM(PurchaseCount)
    /// </summary>
    //[Enum("CONVERT(FLOAT,SUM(DistributeCount)) / SUM(PurchaseCount)")]
    [Enum("Case  WHEN SUM(DistributeCount)=0 THEN 0 WHEN SUM(PurchaseCount)=0 THEN 0  ELSE  CONVERT(FLOAT,SUM(DistributeCount*Price)) / SUM(isnull(PurchaseAmount,0)) END  ")]
    DistributeRate = 0x8,

    /// <summary>
    /// 总配送量
    /// </summary>
    [Enum("SUM(DistributeCount)")]
    DistributeCountTotal = 0x10,
    /// <summary>
    /// 总入库量
    /// </summary>
    [Enum("SUM(WarehouseCount)")]
    WareHouseCountTotal = 0x20,

    /// <summary>
    /// 入库率
    /// SUM( WareHouseCount) / SUM(PurchaseCount)
    /// //[Enum("CONVERT(FLOAT,SUM(WareHouseAmount)) / SUM(PurchaseAmount)")]
    /// </summary>
    //[Enum("CONVERT(FLOAT,SUM(WareHouseCount))/SUM(PurchaseCount)")]         //update by 张雄 2011/4/21
    //WareHouseRate = 0x40,
    //修改者：蒋峰
    //比率问题
    [Enum("Case when sum(WareHouseCount)=0 then 0 when sum(PurchaseCount)=0 then 0 else CONVERT(float, SUM(WarehouseAmount)) / SUM(isnull(PurchaseAmount,0)) end ")]//update by zzr 2009/11/27
    WareHouseRate = 0x40,
    /// <summary>
    /// 入库总金额
    /// SUM(WarehouseAmount)
    /// </summary>
    [Enum("SUM(WarehouseAmount)")]
    WareHouseAmountTotal = 0x80,
    /// <summary>
    /// 采购次数
    /// </summary>
    [Enum("COUNT(OrderID)")]
    CountOrder = 0x100,
    /// <summary>
    /// 配送总金额
    /// </summary>
    [Enum("SUM(DistributeCount*Price)")]
    DistributeAmountTotal = 0x200,
    /// <summary>
    /// 降幅（批量统计）
    /// </summary>
    [Enum("CASE  WHEN SUM(LimitPrice*PurchaseCount) = 0 THEN 0 WHEN SUM(SellPrice*PurchaseCount) = 0 THEN 0 ELSE (SUM(LimitPrice*PurchaseCount)-SUM(SellPrice*PurchaseCount))/SUM(isnull(LimitPrice*PurchaseCount,0)) END")]
    DecreasingAmplitudeBatch = 0x400,
    /// <summary>
    /// 品规
    /// </summary>
    [Enum("COUNT (DISTINCT ProcureCatalogID)")]
    DrugCount = 0x800,

    /// <summary>
    /// 利润
    /// </summary>
    [Enum("SUM(Sellprice * PurchaseCount - Price * PurchaseCount)")]
    Profit = 0x1000,

    /// <summary>
    /// 类别
    /// </summary>
    [Enum("SUM(Sellprice * PurchaseCount - Price * PurchaseCount)")]
    SortName = 0x2000,

    /// <summary>
    /// 退货总金额
    /// </summary>
    [Enum("SUM(CASE WHEN PurchaseCount < 0 THEN - PurchaseCount * Price ELSE 0 END )")]
    ReturnedGoods = 0x4000,

    /// <summary>
    /// 付款总金额
    /// </summary>
    [Enum("SUM(CASE WHEN InvoicePaySerialID IS NOT NULL THEN PurchaseCount * Price ELSE 0 END )")]
    PayOffAmount = 0x8000
}





[Flags]
public enum GroupByField
{
    /// <summary>
    /// 地区
    /// </summary>
    [Enum("SUBSTRING(AreaID,1,4)")]
    AreaID = 0x1,
    /// <summary>
    /// 医院
    /// </summary>
    HospitalID = 0x2,
    /// <summary>
    /// 采购目录
    /// </summary>
    ProcureCatalogID = 0x4,
    /// <summary>
    /// 采购单
    /// </summary>
    OrderID = 0x8,
    /// <summary>
    /// 分类
    /// </summary>
    SortID = 0x10,
    /// <summary>
    /// 生产企业
    /// </summary>
    CompanyName_SC = 0x80,
    /// <summary>
    /// 中标企业
    /// </summary>
    CompanyName_TB = 0x20,
    /// <summary>
    /// 配送企业
    /// </summary>
    CompanyID_PS = 0x40,

    /// <summary>
    /// 质量层次
    /// </summary>
    QualityLevel = 0x100,
    /// <summary>
    /// 年入库
    /// </summary>
    [Enum("YEAR(WareHouseTime)")]
    WareHouseTimeYear = 0x200,
    /// <summary>
    /// 月入库
    /// </summary>
    //[Enum("dbo.GetMonth(WareHouseTime)")]
    [Enum("dbo.fun_GetYearMonth(WareHouseTime)")]            //update by lhl 2009/8/17
    WareHouseTimeMonth = 0x400,
    /// <summary>
    /// 季度入库
    /// </summary>
    [Enum("dbo.GetQuarter(WareHouseTime)")]
    WareHouseTimeQuarter = 0x800,
    /// <summary>
    /// 年采购
    /// </summary>
    [Enum("YEAR(PlanTime)")]
    PurchaseTimeYear = 0x1000,
    /// <summary>
    /// 月采购
    /// </summary>    
    //[Enum("dbo.GetMonth(PlanTime)")]
    [Enum("dbo.fun_GetYearMonth(PlanTime)")]               //update by lhl 2009/8/17
    PurchaseTimeMonth = 0x2000,
    /// <summary>
    /// 月采购
    /// </summary>
    [Enum("dbo.GetQuarter(PlanTime)")]
    PurchaseTimeQuarter = 0x10000,
    /// <summary>
    /// 医保类型
    /// </summary>
    InsuranceType = 0x4000,
    /// <summary>
    /// 医院级别
    /// </summary>
    Levels = 0x8000,
    /// <summary>
    /// 贵重药品统计
    /// </summary>
    IsPrecious = 0x20000,
    /// <summary>
    /// 采购类型 中标 重点监控 备案 未中标
    /// </summary>
    SortSource = 0x40000,
    /// <summary>
    /// 加成率
    /// </summary>
    AdditionRate = 0x80000,

    /// <summary>
    /// 医院名称
    /// </summary>
    HospitalName = 0x100000,
    /// <summary>
    /// 目录名称
    /// </summary>
    ProductName = 0x10000000,
    /// <summary>
    /// 周采购
    /// </summary>
    [Enum("dbo.uf_GetWeekOfYear(PlanTime)")]
    WeekOfYear = 0x2000000

}

/// <summary>
/// 自定义枚举属性
/// </summary>
[global::System.AttributeUsage(System.AttributeTargets.Field, Inherited = true, AllowMultiple = true)]
public sealed class EnumAttribute : System.Attribute
{

    readonly string _Expression;

    public EnumAttribute(string expression)
    {
        this._Expression = expression;

    }
    /// <summary>
    /// 替代表达式
    /// </summary>
    public string Expression
    {
        get { return _Expression; }
    }
}

/// <summary>
/// 映射缓存
/// </summary>
public class EnumMapHelper
{
    // maps用于保存每种枚举及其对应的EnumMap对象
    private static Dictionary<Type, EnumMap> maps;

    // 由于C#中没有static indexer的概念，所以在这里我们用静态方法
    public static string GetStringFromEnum(Enum item)
    {
        if (maps == null)
        {
            maps = new Dictionary<Type, EnumMap>();
        }

        Type enumType = item.GetType();

        EnumMap mapper = null;
        if (maps.ContainsKey(enumType))
        {
            mapper = maps[enumType];
        }
        else
        {
            mapper = new EnumMap(enumType);
            maps.Add(enumType, mapper);
        }
        return mapper[item];
    }

    private class EnumMap
    {
        private Type internalEnumType;
        private Dictionary<Enum, string> map;

        public EnumMap(Type enumType)
        {
            if (!enumType.IsSubclassOf(typeof(Enum)))
            {
                throw new InvalidCastException();
            }
            internalEnumType = enumType;
            FieldInfo[] staticFiles = enumType.GetFields(BindingFlags.Public | BindingFlags.Static);

            map = new Dictionary<Enum, string>(staticFiles.Length);

            for (int i = 0; i < staticFiles.Length; i++)
            {
                if (staticFiles[i].FieldType == enumType)
                {
                    string description = "";
                    object[] attrs = staticFiles[i].GetCustomAttributes(typeof(EnumAttribute), true);
                    description = attrs.Length > 0 ?
                        ((EnumAttribute)attrs[0]).Expression :
                        //若没找到EnumItemDescription标记，则使用该枚举值的名字
                        description = staticFiles[i].Name;

                    map.Add((Enum)staticFiles[i].GetValue(enumType), description);
                }
            }
        }

        public string this[Enum item]
        {
            get
            {
                if (item.GetType() != internalEnumType)
                {
                    throw new ArgumentException();
                }
                return map[item];
            }
        }
    }
}